<?php

declare(strict_types=1);

namespace App\Helpers;

use League\Flysystem\Filesystem;
use OSS\Core\OssException;
use OSS\OssClient;
use Xxtime\Flysystem\Aliyun\OssAdapter;
use AlibabaCloud\SDK\Cloudauth\V20190307\Cloudauth;
use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Cloudauth\V20190307\Models\DescribeVerifyTokenRequest;
use AlibabaCloud\SDK\Cloudauth\V20190307\Models\DescribeVerifyResultRequest;
use AlibabaCloud\SDK\Cloudauth\V20190307\Models\CompareFacesRequest;
use AlibabaCloud\Green\Green;
use AlibabaCloud\Client\AlibabaCloud;
use Endroid\QrCode\Builder\Builder;
use Exception;

class AliyunUtil
{
    /**
     * 图片域名
     * @var string
     */
    const IMG_HOST = 'http://xinyous-photo.oss-cn-shenzhen.aliyuncs.com/'; //http://imgcdn-aliyun.xiaoludd.com/
    const IMG_HOST_V2 = 'http://xinyous-images.oss-cn-shenzhen.aliyuncs.com/';

    /**
     * 音频域名
     * @var string
     */
    const VOICE_HOST = 'http://xinyous-voice.oss-cn-shenzhen.aliyuncs.com/'; //http://voicecdn-aliyun.xiaoludd.com/

    /**
     * 阿里云外网域名
     * @var string
     */
    const END_POINT = "http://oss-cn-shenzhen.aliyuncs.com";

    /**
     * 图片缩略裁剪构造
     * @param $url
     * @param int $width
     * @param int $height
     */
    public static function imageResize($url, $width = 500, $height = 500)
    {
        if (!$url) return '';
        return $url . "?x-oss-process=image/resize,m_fill,h_{$height},w_{$width}";
    }

    /**
     * 返回资源的绝对地址
     *
     * @param string $resource
     * @param string $type   img|voice
     * @return string
     */
    public static function buidResUrl($resource, $type)
    {
        $res = trim($resource);
        if ($res == '') return '';

        switch ($type) {
            case 'img':
                $res = self::IMG_HOST . $res;
                break;
            case 'voice':
                $res = self::VOICE_HOST . $res;
                break;
        }

        return $res;
    }

    /**
     * 模糊图片
     */
    static function blurImage($url = '', $width = 500, $height = 500)
    {
        if (!$url) return '';
        return self::IMG_HOST . $url . "?x-oss-process=image/blur,r_11,s_11/bright,-50/resize,m_fill,h_{$height},w_{$width}";
    }

    /**
     * 阿里云认证client对象
     */
    static function getClient()
    {
        $config = new Config([
            "accessKeyId" => config('aliyun.accessKeyId'),
            "accessKeySecret" => config('aliyun.accessKeySecret'),
        ]);
        // 访问的域名
        $config->endpoint = "cloudauth.aliyuncs.com";
        return new Cloudauth($config);
    }

    /**
     * 阿里云认证 - 获取认证token
     */
    static function getVerifyToken($vrfObject = null)
    {
        try {
            $client = self::getClient();
            // 复制代码运行请自行打印 API 的返回值
            $describeVerifyTokenRequest = new DescribeVerifyTokenRequest($vrfObject);
            // 复制代码运行请自行打印 API 的返回值
            $result = $client->describeVerifyToken($describeVerifyTokenRequest);
            return $result->body;
        } catch (Exception $exception) {
            return false;
        }


    }

    /**
     * 阿里云认证 - 查询认证结果
     */
    static function doVerifyResult($bizNo = '', $vrfyType = 'avatar_check')
    {
        try {
            $client = self::getClient();
            // 复制代码运行请自行打印 API 的返回值
            $describeVerifyResultRequest = new DescribeVerifyResultRequest([
                "bizType" => config('aliyun.verfScene.' . $vrfyType),
                "bizId" => $bizNo,
            ]);
            // 复制代码运行请自行打印 API 的返回值
            $result = $client->describeVerifyResult($describeVerifyResultRequest);
            return $result->body;
        } catch (Exception $exception) {
            $result = new class{};
            $result->verifyStatus = -2;
            return $result;
        }
    }

    /**
     * 创建OSS对象
     */
    static function createOssObj($bucket = 'image', $accountKey = 'xiaolu')
    {
        // $accountKey = 'xiaolu';
        $aliyun = new OssAdapter([
            'accessId'       => config("aliyun.oss.{$accountKey}.accessKeyId"),
            'accessSecret'   => config("aliyun.oss.{$accountKey}.accessKeySecret"),
            'bucket'         => $bucket == 'image' ?
                config("aliyun.oss.{$accountKey}.imageBucket") :
                config("aliyun.oss.{$accountKey}.fileBucket"),
            'endpoint'       => self::END_POINT,
        ]);
        return new Filesystem($aliyun);
    }

    /**
     * 上传图片到OSS
     */
    static function uploadRemotePhoto($remoteImage = '', $fileName = '', $ossPath = 'real_avatar')
    {
        $ret = Helper::downloadFile($remoteImage, $fileName);
        if ($ret['errcode'] != 0) return '';
        $content = $ret['file'];
        $stream = fopen($content, 'r+');
        $filesystem = self::createOssObj('image', 'moliao');
        $filesystem->writeStream($ossPath . '/' . $fileName, $stream);
        if (is_resource($stream)) fclose($stream);
        if (file_exists($content)) unlink($content);
        return "{$ossPath}/{$fileName}";
    }

    /**
     * 两张照片的人脸相似度对比
     */
    static function compareFaces($faces = [], $userId = 0)
    {
        try {
            $client = self::getClient();
            $compareFacesRequest = new CompareFacesRequest([
                "targetImageType" => "FacePic",
                "sourceImageType" => "FacePic",
                "sourceImageValue" => $faces[0],
                "targetImageValue" => $faces[1],
            ]);
            // 复制代码运行请自行打印 API 的返回值
            $result = $client->compareFaces($compareFacesRequest);
            log_info(__METHOD__ . "=={$userId}==Pics:" . json_encode($faces) . "==Ret:" . json_encode($result->body));
            if (!$result->body->success) return 0;
            $score = $result->body->data->similarityScore;
            return $score && $score >= 70 ? 1 : 0;
        } catch (Exception $e) {
            return 0;
        }
    }

    /**
     * 图片审核
     */
    static function imgCheck($imgUrl = '')
    {
        $client = self::getClient();
        AlibabaCloud::accessKeyClient(config('aliyun.accessKeyId'), config('aliyun.accessKeySecret'))->regionId('cn-shenzhen')->asDefaultClient();
        $task1 = array(
            'dataId' => '1',
            'url' => $imgUrl
        );
        try {
            $response = Green::v20180509()->imageSyncScan()->body(json_encode([
                'tasks' => [$task1],
                'scenes' => ['porn', 'terrorism', 'ad'],
                'bizType' => 'private_chat'
            ]))->request();
            $result = $response->toArray();
            if (200 == $response->code) {
                $taskResults = $response->data;
                $retData = [];
                foreach ($taskResults as $taskResult) {
                    if (200 == $taskResult->code) {
                        $sceneResults = $taskResult->results;
                        foreach ($sceneResults as $sceneResult) {
                            $scene = $sceneResult->scene;
                            $suggestion = $sceneResult->suggestion;
                            // 根据scene和suggetion做相关的处理
                            $retData[$scene] = $suggestion;
                        }
                        $ret = ['errcode' => 0, 'data' => $retData, 'allbody' => $result['data']];
                    } else {
                        $ret = ['errcode' => $response->code, 'errmsg' => 'task process fail'];
                    }
                }
            } else {
                $ret = ['errcode' => $response->code, 'errmsg' => 'detect not success'];
            }
        } catch (Exception $exception) {
            $ret = ['errcode' => -1, 'errmsg' => $exception->getMessage()];
        }
        return $ret;
    }

    /**
     * 图片是否通过检测
     */
    static function passImgCheck($imgUrl = '')
    {
        $ret = self::imgCheck($imgUrl);
        if ($ret['errcode'] != 0) return true;
        foreach ($ret['data'] as $scene => $result) {
            if ($result == 'block') return false;
        }
        return true;
    }

    /**
     * @param array $files
     */
    static function uploadImgRemote($files = [],$bucket = 'image', $accountKey = 'dengliao')
    {
        if(empty($files)) return ['code'=>-1,'msg'=>'请选择要上传的图片','info'=>[]];
        $config = [
            'accessId'       => config("aliyun.oss.{$accountKey}.accessKeyId"),
            'accessSecret'   => config("aliyun.oss.{$accountKey}.accessKeySecret"),
            'bucket'         => $bucket == 'image' ?
                config("aliyun.oss.{$accountKey}.imageBucket") :
                config("aliyun.oss.{$accountKey}.fileBucket"),
            'endpoint'       => self::END_POINT,
        ];
        $name = $files->getClientFilename();
        $format = strrchr($name, '.');
        $object = 'complaint/'.sha1(date('YmdHis', time()) . uniqid()) . $format;
        $filePath = $files->getPathname();
        try{
            $ossClient = new OssClient($config['accessId'],  $config['accessSecret'], $config['endpoint']);
            $resource = $ossClient->uploadFile($config['bucket'], $object, $filePath);
            print_r($resource);
            if(empty($resource['info']['url'])) return ['code'=>-1,'msg'=>'图片上传失败','info'=>[]];
            return ['code'=>200,'msg'=>'success','info'=>['url'=>$object]];
        } catch(OssException $e) {
            log_info(__METHOD__ . "=Pics:" . json_encode($e->getMessage()) . "==Ret:" );
            return ['code'=>-1,'msg'=>'图片上传失败','data'=>[]];
        }
    }

    /**
     * 生成水印图
     * @param string $url 二维码内容
     * @param string $qrCodeFileName 二维码存放地址
     * @param string $bgFileName 背景图地址
     * @return false|string
     * @throws \League\Flysystem\FileExistsException
     */
    static function posterQrCode($url, $qrCodeFileName, $bgFileName, $size = 150,$x=60,$y=55)
    {
        //生成二维码
        $imageData = Builder::create()
            ->data($url)
            ->size($size)
            ->margin(15)
            ->build()->getString();
        $filesystem = self::createOssObj('image', 'moliao');
        $ok = $filesystem->write($qrCodeFileName, $imageData);

        if (!$ok) {
            return false;
        }
        $base64 = base64_encode($qrCodeFileName);
        $base64 = str_replace(array('+', '/', '='), array('-', '_', ''), $base64);
        $image = $bgFileName . '?x-oss-process=image/watermark,image_' . $base64 . ",g_se,x_{$x},y_{$y}";
        return $image;
    }
}
